package config

import (
	"net/http"

	"github.com/glennliao/apijson-go/consts"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/samber/lo"
)

type FieldsGetValue struct {
	In       map[string][]string
	Out      map[string]string
	MaxCount *int // 可使用的最大分页大小,默认100
}

type F访问配置结构 struct {
	T调试级别   int8
	M名称     string
	B别名     string
	H获取权限   []string
	T头部权限   []string
	P批量获取权限 []string
	P批量头部权限 []string
	T提交权限   []string
	G更新权限   []string
	S删除权限   []string
	C创建时间   *gtime.Time
	X详情     string

	Z主键生成策略 string // 主键生成策略
	Z主键字段   string
	Z字段获取配置 map[string]*FieldsGetValue
	Z执行器    string
}

func (配置 *F访问配置结构) G根据角色获取输出字段(角色 string) []string {
	var 字段映射 map[string]string

	if 值, 存在 := 配置.Z字段获取配置[角色]; 存在 {
		字段映射 = 值.Out
	} else {
		字段映射 = 配置.Z字段获取配置["default"].Out
	}
	return lo.Keys(字段映射)
}

func (配置 *F访问配置结构) G根据角色获取输入字段(角色 string) map[string][]string {
	var 输入字段映射 map[string][]string

	if 值, 存在 := 配置.Z字段获取配置[角色]; 存在 {
		输入字段映射 = 值.In
	} else {
		输入字段映射 = 配置.Z字段获取配置["default"].In
	}

	return 输入字段映射
}

func (访问 *F访问控制) H获取访问配置(访问名称 string, 不验证 bool) (*F访问配置结构, error) {
	配置, 存在 := 访问.F访问配置映射[访问名称]

	if !存在 {
		if 不验证 {
			return &F访问配置结构{
				T调试级别: 0,
				M名称:   访问名称,
				B别名:   访问名称,
			}, nil
		}
		return nil, consts.X新建访问配置未找到错误(访问名称)
	}

	return &配置, nil
}

func (访问 *F访问控制) H获取访问角色(访问名称 string, 方法 string) ([]string, string, error) {
	配置, 存在 := 访问.F访问配置映射[访问名称]

	if !存在 {
		return nil, "", consts.X新建访问配置未找到错误(访问名称)
	}

	switch 方法 {
	case http.MethodGet:
		return 配置.H获取权限, 配置.M名称, nil
	case http.MethodHead:
		return 配置.T头部权限, 配置.M名称, nil
	case http.MethodPost:
		return 配置.T提交权限, 配置.M名称, nil
	case http.MethodPut:
		return 配置.G更新权限, 配置.M名称, nil
	case http.MethodDelete:
		return 配置.S删除权限, 配置.M名称, nil
	}

	return []string{}, 配置.M名称, nil
}
